package common

import (
	"fmt"
	"strings"
	"think/config"
	"think/database"
)

// ConditionType 条件类型
type ConditionType int

const (
	EQ    ConditionType = iota // 等于
	NEQ                        // 不等于
	GT                         // 大于
	LT                         // 小于
	GTE                        // 大于等于
	LTE                        // 小于等于
	LIKE                       // 模糊匹配
	IN                         // IN条件
	NOTIN                      // NOT IN条件
)

// Condition 条件结构体
type Condition struct {
	Field    string
	Type     ConditionType
	Value    interface{}
	Relation string // AND 或 OR
}

// Model 模型基类
type Model struct {
	table    string
	where    []Condition
	order    []string
	group    []string
	having   []string
	limit    int
	offset   int
	field    []string
	distinct bool
}

// NewModel 创建一个新的模型实例
func NewModel(table string) *Model {
	return &Model{
		table: table,
	}
}

// Table 设置表名
func (m *Model) Table(table string) *Model {
	m.table = table
	return m
}

// Field 设置查询字段
func (m *Model) Field(fields ...string) *Model {
	m.field = append(m.field, fields...)
	return m
}

// Distinct 设置DISTINCT
func (m *Model) Distinct() *Model {
	m.distinct = true
	return m
}

// Where 添加查询条件（使用Condition结构体）
func (m *Model) Where(condition Condition) *Model {
	m.where = append(m.where, condition)
	return m
}

// WhereEQ 添加等于条件
func (m *Model) WhereEQ(field string, value interface{}) *Model {
	m.where = append(m.where, Condition{
		Field:    field,
		Type:     EQ,
		Value:    value,
		Relation: "AND",
	})
	return m
}

// WhereNEQ 添加不等于条件
func (m *Model) WhereNEQ(field string, value interface{}) *Model {
	m.where = append(m.where, Condition{
		Field:    field,
		Type:     NEQ,
		Value:    value,
		Relation: "AND",
	})
	return m
}

// WhereGT 添加大于条件
func (m *Model) WhereGT(field string, value interface{}) *Model {
	m.where = append(m.where, Condition{
		Field:    field,
		Type:     GT,
		Value:    value,
		Relation: "AND",
	})
	return m
}

// WhereLT 添加小于条件
func (m *Model) WhereLT(field string, value interface{}) *Model {
	m.where = append(m.where, Condition{
		Field:    field,
		Type:     LT,
		Value:    value,
		Relation: "AND",
	})
	return m
}

// WhereGTE 添加大于等于条件
func (m *Model) WhereGTE(field string, value interface{}) *Model {
	m.where = append(m.where, Condition{
		Field:    field,
		Type:     GTE,
		Value:    value,
		Relation: "AND",
	})
	return m
}

// WhereLTE 添加小于等于条件
func (m *Model) WhereLTE(field string, value interface{}) *Model {
	m.where = append(m.where, Condition{
		Field:    field,
		Type:     LTE,
		Value:    value,
		Relation: "AND",
	})
	return m
}

// WhereLike 添加模糊匹配条件
func (m *Model) WhereLike(field string, value string) *Model {
	m.where = append(m.where, Condition{
		Field:    field,
		Type:     LIKE,
		Value:    value,
		Relation: "AND",
	})
	return m
}

// WhereIN 添加IN条件
func (m *Model) WhereIN(field string, value []interface{}) *Model {
	m.where = append(m.where, Condition{
		Field:    field,
		Type:     IN,
		Value:    value,
		Relation: "AND",
	})
	return m
}

// WhereNOTIN 添加NOT IN条件
func (m *Model) WhereNOTIN(field string, value []interface{}) *Model {
	m.where = append(m.where, Condition{
		Field:    field,
		Type:     NOTIN,
		Value:    value,
		Relation: "AND",
	})
	return m
}

// WhereOr 添加OR条件
func (m *Model) WhereOr(field string, value interface{}) *Model {
	m.where = append(m.where, Condition{
		Field:    field,
		Type:     EQ,
		Value:    value,
		Relation: "OR",
	})
	return m
}

// Order 添加排序
func (m *Model) Order(field string, direction string) *Model {
	if direction != "" && direction != "ASC" && direction != "DESC" {
		direction = "ASC"
	}
	m.order = append(m.order, fmt.Sprintf("%s %s", field, direction))
	return m
}

// Group 添加分组
func (m *Model) Group(fields ...string) *Model {
	m.group = append(m.group, fields...)
	return m
}

// Having 添加HAVING条件
func (m *Model) Having(having string) *Model {
	m.having = append(m.having, having)
	return m
}

// Limit 设置查询数量
func (m *Model) Limit(limit int) *Model {
	m.limit = limit
	return m
}

// Offset 设置偏移量
func (m *Model) Offset(offset int) *Model {
	m.offset = offset
	return m
}

// Page 设置分页
func (m *Model) Page(page, pageSize int) *Model {
	if page < 1 {
		page = 1
	}
	if pageSize < 1 {
		pageSize = 10
	}
	m.offset = (page - 1) * pageSize
	m.limit = pageSize
	return m
}

// Get 根据主键获取数据
func (m *Model) Get(id interface{}) interface{} {
	// 构建SQL
	sql := fmt.Sprintf("SELECT * FROM %s WHERE id = ? LIMIT 1", m.table)
	rows, err := database.Query(sql, id)
	if err != nil {
		fmt.Printf("GET查询失败: %v\n", err)
		return nil
	}
	defer rows.Close()

	// 获取列名
	columns, err := rows.Columns()
	if err != nil {
		fmt.Printf("获取列名失败: %v\n", err)
		return nil
	}

	// 创建列值容器
	values := make([]interface{}, len(columns))
	valuePtrs := make([]interface{}, len(columns))
	for i := range columns {
		valuePtrs[i] = &values[i]
	}

	// 扫描单行数据
	if rows.Next() {
		if err := rows.Scan(valuePtrs...); err != nil {
			fmt.Printf("扫描数据失败: %v\n", err)
			return nil
		}

		// 构建结果map
		result := make(map[string]interface{})
		for i, col := range columns {
			val := values[i]
			// 处理NULL值
			if val == nil {
				result[col] = nil
			} else if b, ok := val.([]byte); ok {
				// 处理字符串和二进制数据
				result[col] = string(b)
			} else {
				result[col] = val
			}
		}

		return result
	}

	return nil
}

// Find 查询多条数据
func (m *Model) Find() []interface{} {
	// 构建SQL
	sql := m.buildQuerySQL()
	rows, err := database.Query(sql)
	if err != nil {
		fmt.Printf("Find查询失败: %v\n", err)
		return []interface{}{}
	}
	defer rows.Close()

	// 获取列名
	columns, err := rows.Columns()
	if err != nil {
		fmt.Printf("获取列名失败: %v\n", err)
		return []interface{}{}
	}

	// 创建结果集
	results := make([]interface{}, 0)

	// 创建列值容器
	values := make([]interface{}, len(columns))
	valuePtrs := make([]interface{}, len(columns))
	for i := range columns {
		valuePtrs[i] = &values[i]
	}

	// 扫描多行数据
	for rows.Next() {
		if err := rows.Scan(valuePtrs...); err != nil {
			fmt.Printf("扫描数据失败: %v\n", err)
			continue
		}

		// 构建结果map
		result := make(map[string]interface{})
		for i, col := range columns {
			val := values[i]
			// 处理NULL值
			if val == nil {
				result[col] = nil
			} else if b, ok := val.([]byte); ok {
				// 处理字符串和二进制数据
				result[col] = string(b)
			} else {
				result[col] = val
			}
		}

		results = append(results, result)
	}

	return results
}

// FindOne 查询单条数据
func (m *Model) FindOne() interface{} {
	// 构建SQL
	m.Limit(1)
	sql := m.buildQuerySQL()
	rows, err := database.Query(sql)
	if err != nil {
		fmt.Printf("FindOne查询失败: %v\n", err)
		return nil
	}
	defer rows.Close()

	// 获取列名
	columns, err := rows.Columns()
	if err != nil {
		fmt.Printf("获取列名失败: %v\n", err)
		return nil
	}

	// 创建列值容器
	values := make([]interface{}, len(columns))
	valuePtrs := make([]interface{}, len(columns))
	for i := range columns {
		valuePtrs[i] = &values[i]
	}

	// 扫描单行数据
	if rows.Next() {
		if err := rows.Scan(valuePtrs...); err != nil {
			fmt.Printf("扫描数据失败: %v\n", err)
			return nil
		}

		// 构建结果map
		result := make(map[string]interface{})
		for i, col := range columns {
			val := values[i]
			// 处理NULL值
			if val == nil {
				result[col] = nil
			} else if b, ok := val.([]byte); ok {
				// 处理字符串和二进制数据
				result[col] = string(b)
			} else {
				result[col] = val
			}
		}

		return result
	}

	return nil
}

// Count 查询记录数量
func (m *Model) Count() int64 {
	// 构建SQL
	sql := m.buildQuerySQL("COUNT(*)")
	var count int64
	err := database.DB.QueryRow(sql).Scan(&count)
	if err != nil {
		fmt.Printf("Count查询失败: %v\n", err)
		return 0
	}
	return count
}

// Sum 计算字段总和
func (m *Model) Sum(field string) float64 {
	// 构建SQL
	sql := m.buildQuerySQL(fmt.Sprintf("SUM(%s)", field))
	var sum float64
	err := database.DB.QueryRow(sql).Scan(&sum)
	if err != nil {
		fmt.Printf("Sum查询失败: %v\n", err)
		return 0
	}
	return sum
}

// Save 保存数据
func (m *Model) Save(data map[string]interface{}) bool {
	// 构建INSERT语句
	var fields []string
	var values []interface{}
	var placeholders []string

	for field, value := range data {
		fields = append(fields, field)
		values = append(values, value)
		placeholders = append(placeholders, "?")
	}

	// 构建带前缀的表名
	fullTableName := config.DBConfig.Prefix + m.table
	sql := fmt.Sprintf("INSERT INTO %s (%s) VALUES (%s)",
		fullTableName,
		strings.Join(fields, ", "),
		strings.Join(placeholders, ", "))

	// 执行插入
	_, err := database.Exec(sql, values...)
	if err != nil {
		fmt.Printf("Save操作失败: %v\n", err)
		return false
	}

	return true
}

// Update 更新数据
func (m *Model) Update(data map[string]interface{}) bool {
	// 构建UPDATE语句
	var setClauses []string
	var values []interface{}

	for field, value := range data {
		setClauses = append(setClauses, fmt.Sprintf("%s = ?", field))
		values = append(values, value)
	}

	// 构建带前缀的表名
	fullTableName := config.DBConfig.Prefix + m.table
	sql := fmt.Sprintf("UPDATE %s SET %s", fullTableName, strings.Join(setClauses, ", "))

	// 添加WHERE条件
	if len(m.where) > 0 {
		sql += " WHERE"
		for i, cond := range m.where {
			if i > 0 {
				sql += " " + cond.Relation
			}
			sql += m.buildConditionSQL(cond)
		}
	}

	// 执行更新
	result, err := database.Exec(sql, values...)
	if err != nil {
		fmt.Printf("Update操作失败: %v\n", err)
		return false
	}

	// 检查影响的行数
	affectedRows, err := result.RowsAffected()
	if err != nil {
		fmt.Printf("获取影响行数失败: %v\n", err)
		return false
	}

	return affectedRows > 0
}

// Delete 删除数据
func (m *Model) Delete() bool {
	// 构建带前缀的表名
	fullTableName := config.DBConfig.Prefix + m.table
	// 构建DELETE语句
	sql := fmt.Sprintf("DELETE FROM %s", fullTableName)

	// 添加WHERE条件
	if len(m.where) > 0 {
		sql += " WHERE"
		for i, cond := range m.where {
			if i > 0 {
				sql += " " + cond.Relation
			}
			sql += m.buildConditionSQL(cond)
		}
	}

	// 执行删除
	result, err := database.Exec(sql)
	if err != nil {
		fmt.Printf("Delete操作失败: %v\n", err)
		return false
	}

	// 检查影响的行数
	affectedRows, err := result.RowsAffected()
	if err != nil {
		fmt.Printf("获取影响行数失败: %v\n", err)
		return false
	}

	return affectedRows > 0
}

// buildQuerySQL 构建查询SQL（内部方法）
func (m *Model) buildQuerySQL(fields ...string) string {
	// 构建查询字段
	queryFields := "*"
	if len(fields) > 0 {
		queryFields = fields[0]
	} else if len(m.field) > 0 {
		queryFields = strings.Join(m.field, ", ")
	}

	// 构建DISTINCT
	distinctStr := ""
	if m.distinct {
		distinctStr = "DISTINCT "
	}

	// 构建带前缀的表名
	fullTableName := config.DBConfig.Prefix + m.table
	// 构建SQL
	sql := fmt.Sprintf("SELECT %s%s FROM %s", distinctStr, queryFields, fullTableName)

	// 构建WHERE条件
	if len(m.where) > 0 {
		sql += " WHERE"
		for i, cond := range m.where {
			if i > 0 {
				sql += " " + cond.Relation
			}
			sql += m.buildConditionSQL(cond)
		}
	}

	// 构建GROUP BY
	if len(m.group) > 0 {
		sql += " GROUP BY " + strings.Join(m.group, ", ")
	}

	// 构建HAVING
	if len(m.having) > 0 {
		sql += " HAVING " + strings.Join(m.having, " AND ")
	}

	// 构建ORDER BY
	if len(m.order) > 0 {
		sql += " ORDER BY " + strings.Join(m.order, ", ")
	}

	// 构建LIMIT和OFFSET
	if m.limit > 0 {
		sql += fmt.Sprintf(" LIMIT %d", m.limit)
		if m.offset > 0 {
			sql += fmt.Sprintf(" OFFSET %d", m.offset)
		}
	}

	fmt.Printf("构建的SQL: %s\n", sql)
	return sql
}

// buildConditionSQL 构建条件SQL（内部方法）
func (m *Model) buildConditionSQL(cond Condition) string {
	field := cond.Field
	value := cond.Value

	switch cond.Type {
	case EQ:
		return fmt.Sprintf(" %s = '%v'", field, value)
	case NEQ:
		return fmt.Sprintf(" %s != '%v'", field, value)
	case GT:
		return fmt.Sprintf(" %s > '%v'", field, value)
	case LT:
		return fmt.Sprintf(" %s < '%v'", field, value)
	case GTE:
		return fmt.Sprintf(" %s >= '%v'", field, value)
	case LTE:
		return fmt.Sprintf(" %s <= '%v'", field, value)
	case LIKE:
		return fmt.Sprintf(" %s LIKE '%%%v%%'", field, value)
	case IN:
		if arr, ok := value.([]interface{}); ok {
			var values []string
			for _, v := range arr {
				values = append(values, fmt.Sprintf("'%v'", v))
			}
			return fmt.Sprintf(" %s IN (%s)", field, strings.Join(values, ","))
		}
	case NOTIN:
		if arr, ok := value.([]interface{}); ok {
			var values []string
			for _, v := range arr {
				values = append(values, fmt.Sprintf("'%v'", v))
			}
			return fmt.Sprintf(" %s NOT IN (%s)", field, strings.Join(values, ","))
		}
	}

	return ""
}

// Reset 重置查询条件
func (m *Model) Reset() *Model {
	m.where = []Condition{}
	m.order = []string{}
	m.group = []string{}
	m.having = []string{}
	m.limit = 0
	m.offset = 0
	m.field = []string{}
	m.distinct = false
	return m
}
